home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termHotkeys.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  7KB  |  421 lines

  1. /*
  2. **    termHotkeys.c
  3. **
  4. **    Hotkey support routines.
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. enum    {    CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY,CX_ABORTAREXX };
  13.  
  14.     /* Asynchronous hotkey task. */
  15.  
  16. STATIC struct Process *CxProcess;
  17.  
  18.     /* Hotkey(STRPTR Code,struct MsgPort *Port,LONG ID):
  19.      *
  20.      *    A custom version of the amiga.lib supplied code.
  21.      */
  22.  
  23. STATIC CxObj * __regargs
  24. CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
  25. {
  26.     CxObj *Filter;
  27.  
  28.     if(Filter = CxFilter(Code))
  29.     {
  30.         CxObj *Sender;
  31.  
  32.         if(Sender = CxSender(Port,ID))
  33.         {
  34.             CxObj *Translator;
  35.  
  36.             AttachCxObj(Filter,Sender);
  37.  
  38.             if(Translator = CxTranslate(NULL))
  39.             {
  40.                 AttachCxObj(Filter,Translator);
  41.  
  42.                 if(!CxObjError(Filter))
  43.                     return(Filter);
  44.             }
  45.         }
  46.  
  47.         DeleteCxObjAll(Filter);
  48.     }
  49.  
  50.     return(NULL);
  51. }
  52.  
  53.     /* CreateBroker(struct MsgPort *CxPort):
  54.      *
  55.      *    Set up a CxObj commodity broker.
  56.      */
  57.  
  58. STATIC CxObj * __regargs
  59. CreateBroker(struct MsgPort *CxPort)
  60. {
  61.     CxObj *Broker;
  62.  
  63.         /* Set the commodity priority. */
  64.  
  65.     NewTermBroker . nb_Pri = Hotkeys . CommodityPriority;
  66.  
  67.         /* Create the broker. */
  68.  
  69.     if(Broker = CxBroker(&NewTermBroker,NULL))
  70.     {
  71.             /* Add the hotkeys. */
  72.  
  73.         AttachCxObj(Broker,CustomHotKey(Hotkeys . termScreenToFront,    CxPort,CX_TERMSCREENTOFRONT));
  74.         AttachCxObj(Broker,CustomHotKey(Hotkeys . BufferScreenToFront,    CxPort,CX_BUFFERSCREENTOFRONT));
  75.         AttachCxObj(Broker,CustomHotKey(Hotkeys . SkipDialEntry,    CxPort,CX_SKIPDIALENTRY));
  76.         AttachCxObj(Broker,CustomHotKey(Hotkeys . AbortARexx,        CxPort,CX_ABORTAREXX));
  77.  
  78.             /* Did an error show up? */
  79.  
  80.         if(!CxObjError(Broker))
  81.         {
  82.                 /* Broker has been added, now activate it. */
  83.  
  84.             ActivateCxObj(Broker,Hotkeys . HotkeysEnabled);
  85.  
  86.             return(Broker);
  87.         }
  88.  
  89.         DeleteCxObjAll(Broker);
  90.     }
  91.  
  92.     return(NULL);
  93. }
  94.  
  95.     /* TermCxServer():
  96.      *
  97.      *    Asynchronous hotkey server.
  98.      */
  99.  
  100. STATIC VOID __saveds
  101. TermCxServer(VOID)
  102. {
  103.     CxObj        *Broker;
  104.     struct MsgPort    *CxPort;
  105.     CxMsg        *Message;
  106.  
  107.         /* Create a reply port. */
  108.  
  109.     if(CxPort = CreateMsgPort())
  110.     {
  111.             /* Add the port to the public list. */
  112.  
  113.         CxPort -> mp_Node . ln_Name = NewTermBroker . nb_Name;
  114.  
  115.         AddPort(CxPort);
  116.  
  117.             /* Install the port. */
  118.  
  119.         NewTermBroker . nb_Port    = CxPort;
  120.  
  121.             /* Create the broker. */
  122.  
  123.         if(Broker = CreateBroker(CxPort))
  124.         {
  125.             ULONG    SignalSet;
  126.             BYTE    Terminated = FALSE;
  127.  
  128.                 /* Signal father task that we're done. */
  129.  
  130.             Signal(ThisProcess,SIG_HANDSHAKE);
  131.  
  132.                 /* Loop and loop... */
  133.  
  134.             while(!Terminated)
  135.             {
  136.                     /* Wait for some signal. */
  137.  
  138.                 SignalSet = Wait(SIG_KILL | SIG_RESET | PORTMASK(CxPort));
  139.  
  140.                     /* ^C aborts. */
  141.  
  142.                 if(SignalSet & SIG_KILL)
  143.                     Terminated = TRUE;
  144.  
  145.                     /* ^D removes the broker and
  146.                      * creates a new one.
  147.                      */
  148.  
  149.                 if(SignalSet & SIG_RESET)
  150.                 {
  151.                     DeleteCxObjAll(Broker);
  152.  
  153.                     Broker = CreateBroker(CxPort);
  154.                 }
  155.  
  156.                     /* A commodity message. */
  157.  
  158.                 if(SignalSet & PORTMASK(CxPort))
  159.                 {
  160.                     ULONG MessageType,MessageID;
  161.  
  162.                         /* Remove all messages. */
  163.  
  164.                     while(Message = (CxMsg *)GetMsg(CxPort))
  165.                     {
  166.                             /* Extract type and ID. */
  167.  
  168.                         MessageType    = CxMsgID(Message);
  169.                         MessageID    = CxMsgType(Message);
  170.  
  171.                         ReplyMsg((struct Message *)Message);
  172.  
  173.                             /* Take a look at the type... */
  174.  
  175.                         switch(MessageID)
  176.                         {
  177.                                 /* A hotkey was pressed. */
  178.  
  179.                             case CXM_IEVENT:
  180.  
  181.                                 switch(MessageType)
  182.                                 {
  183.                                     case CX_TERMSCREENTOFRONT:
  184.  
  185.                                         Forbid();
  186.  
  187.                                         if(Window)
  188.                                             BumpWindow(TopWindow);
  189.                                         else
  190.                                             Signal(ThisProcess,SIGBREAKF_CTRL_F);
  191.  
  192.                                         Permit();
  193.  
  194.                                         break;
  195.  
  196.                                     case CX_BUFFERSCREENTOFRONT:
  197.  
  198.                                         LaunchBuffer();
  199.                                         break;
  200.  
  201.                                     case CX_SKIPDIALENTRY:
  202.  
  203.                                         Signal(ThisProcess,SIG_SKIP);
  204.                                         break;
  205.  
  206.                                     case CX_ABORTAREXX:
  207.  
  208.                                         if(InRexx)
  209.                                             Signal(ThisProcess,SIG_BREAK);
  210.  
  211.                                         break;
  212.                                 }
  213.  
  214.                                 break;
  215.  
  216.                                 /* An internal commodity command. */
  217.  
  218.                             case CXM_COMMAND:
  219.  
  220.                                 switch(MessageType)
  221.                                 {
  222.                                     case CXCMD_DISABLE:
  223.  
  224.                                         ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = FALSE);
  225.                                         break;
  226.  
  227.                                     case CXCMD_ENABLE:
  228.  
  229.                                         ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = TRUE);
  230.                                         break;
  231.                                 }
  232.  
  233.                                 break;
  234.                         }
  235.                     }
  236.                 }
  237.             }
  238.  
  239.                 /* Remove the broker. */
  240.  
  241.             DeleteCxObjAll(Broker);
  242.         }
  243.  
  244.             /* Remove the port from the public list. */
  245.  
  246.         RemPort(CxPort);
  247.  
  248.             /* Remove all pendig messages. */
  249.  
  250.         while(Message = (CxMsg *)GetMsg(CxPort))
  251.             ReplyMsg((struct Message *)Message);
  252.  
  253.             /* Delete the reply port. */
  254.  
  255.         DeleteMsgPort(CxPort);
  256.     }
  257.  
  258.     Forbid();
  259.  
  260.         /* Clear the task ID. */
  261.  
  262.     CxProcess = NULL;
  263.  
  264.         /* Signal father process that we're done. */
  265.  
  266.     Signal(ThisProcess,SIG_HANDSHAKE);
  267. }
  268.  
  269.     /* ShutdownCx():
  270.      *
  271.      *    Remove the hotkey task.
  272.      */
  273.  
  274. VOID
  275. ShutdownCx()
  276. {
  277.     if(CxProcess)
  278.     {
  279.         Forbid();
  280.  
  281.         Signal(CxProcess,SIG_KILL);
  282.  
  283.         ClrSignal(SIG_HANDSHAKE);
  284.  
  285.         Wait(SIG_HANDSHAKE);
  286.  
  287.         Permit();
  288.     }
  289. }
  290.  
  291.     /* SetupCx():
  292.      *
  293.      *    Create the hotkey task.
  294.      */
  295.  
  296. BYTE
  297. SetupCx()
  298. {
  299.         /* If the task is already running, tell it to
  300.          * update the hotkey settings.
  301.          */
  302.  
  303.     if(CxProcess)
  304.     {
  305.         Signal(CxProcess,SIG_RESET);
  306.  
  307.         return(TRUE);
  308.     }
  309.     else
  310.     {
  311.         Forbid();
  312.  
  313.         if(CxProcess = (struct Process *)CreateNewProcTags(
  314.             NP_Entry,    TermCxServer,
  315.             NP_Name,    "term Hotkey Process",
  316.             NP_Priority,    0,
  317.             NP_StackSize,    8192,
  318.             NP_WindowPtr,    -1,
  319.         TAG_END))
  320.         {
  321.             ClrSignal(SIG_HANDSHAKE);
  322.  
  323.             Wait(SIG_HANDSHAKE);
  324.         }
  325.  
  326.         Permit();
  327.  
  328.         if(CxProcess)
  329.             return(TRUE);
  330.     }
  331.  
  332.     return(FALSE);
  333. }
  334.  
  335.     /* LoadHotkeys(STRPTR Name,struct Hotkeys *Keys):
  336.      *
  337.      *    Load the hotkey settings from a file.
  338.      */
  339.  
  340. BYTE __regargs
  341. LoadHotkeys(STRPTR Name,struct Hotkeys *Keys)
  342. {
  343.     struct IFFHandle    *Handle;
  344.     BYTE             Success = FALSE;
  345.     struct StoredProperty    *Prop;
  346.     struct TermInfo        *TermInfo;
  347.     LONG             Error = 0;
  348.  
  349.     if(Handle = AllocIFF())
  350.     {
  351.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  352.         {
  353.             InitIFFasDOS(Handle);
  354.  
  355.             if(!(Error = OpenIFF(Handle,IFFF_READ)))
  356.             {
  357.                 /* Collect version number ID if
  358.                  * available.
  359.                  */
  360.  
  361.                 if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
  362.                 {
  363.                     /* The following line tells iffparse to stop at the
  364.                      * very beginning of a `Type' chunk contained in a
  365.                      * `TERM' FORM chunk.
  366.                      */
  367.  
  368.                     if(!(Error = StopChunk(Handle,ID_TERM,ID_HOTK)))
  369.                     {
  370.                         /* Parse the file... */
  371.  
  372.                         if(!ParseIFF(Handle,IFFPARSE_SCAN))
  373.                         {
  374.                             /* Did we get a version ID? */
  375.  
  376.                             if(Prop = FindProp(Handle,ID_TERM,ID_VERS))
  377.                             {
  378.                                 TermInfo = (struct TermInfo *)Prop -> sp_Data;
  379.  
  380.                                 if((TermInfo -> Version < CONFIG_FILE_VERSION) || (TermInfo -> Version == CONFIG_FILE_VERSION && TermInfo -> Revision < CONFIG_FILE_REVISION))
  381.                                 {
  382.                                     if(ReadChunkBytes(Handle,Keys,sizeof(struct HotkeysOld)) == sizeof(struct HotkeysOld))
  383.                                     {
  384.                                         strcpy(Keys -> AbortARexx,"lshift rshift escape");
  385.  
  386.                                         Success = TRUE;
  387.                                     }
  388.                                     else
  389.                                         Error = IoErr();
  390.                                 }
  391.                                 else
  392.                                 {
  393.                                     if(ReadChunkBytes(Handle,Keys,sizeof(struct Hotkeys)) == sizeof(struct Hotkeys))
  394.                                         Success = TRUE;
  395.                                     else
  396.                                         Error = IoErr();
  397.                                 }
  398.                             }
  399.                         }
  400.                     }
  401.                 }
  402.  
  403.                 CloseIFF(Handle);
  404.             }
  405.  
  406.             Close(Handle -> iff_Stream);
  407.         }
  408.         else
  409.             Error = IoErr();
  410.  
  411.         FreeIFF(Handle);
  412.     }
  413.     else
  414.         Error = ERR_NO_MEM;
  415.  
  416.     if(Error)
  417.         SetIoErr(Error);
  418.  
  419.     return(Success);
  420. }
  421.